﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using VMMove.Business;
using System.IO;
using nVentive.Umbrella.Extensions;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Xml.Linq;
using System.Xml.XPath;
using System.Text.RegularExpressions;
using System.Diagnostics;
using HyperVMover;

namespace VMMove.Models
{
    public class VMListView : INotifyPropertyChanged
    {
        static string hyperVRootPath = Path.Combine(
            Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
            @"Microsoft\Windows\Hyper-V");

        private VirtualMachine _currentVM;

        public event Action<string> NewMessage = delegate { };

        public VMListView()
        {
            HyperVUtils.LogMessage += m => NewMessage(m);
            Machines = new BindingList<VirtualMachine>();
        }

        public void UpdateList()
        {
            if (Directory.Exists(hyperVRootPath))
            {
                Machines.Clear();

                var files = from file in Directory.GetFiles(Path.Combine(hyperVRootPath, "Virtual Machines"), "*.xml")
                            select new VirtualMachine(file);

                files.ForEach(Machines.Add);
            }
            else
            {
                NewMessage(string.Format("Cannot find Hyper-V configuration files in [{0}]", hyperVRootPath));
            }
        }

        internal void UnlinkCurrent()
        {
            if (_currentVM != null)
            {
                NewMessage(string.Format("Trying to detach VM {0}", _currentVM.Name));
                HyperVUtils.DetachVM(_currentVM.Name);
                NewMessage("Done");
                UpdateList();
            }
        }

        public void LinkMachine(string path)
        {
            NewMessage(string.Format("Trying to attach VM in {0}", path));
            HyperVUtils.AttachVM(path);
            NewMessage("Done");

            UpdateList();
        }

        public VirtualMachine SelectedMachine
        {
            get {
                return _currentVM;
            }
            set
            {
                _currentVM = value;
                PropertyChanged(this, new PropertyChangedEventArgs("CanUnlinkCurrent"));
            }
        }

        public bool CanUnlinkCurrent
        {
            get
            {
                if (SelectedMachine != null)
                {
                    var state = SelectedMachine.State;

                    return state == HyperVMover.VMState.Disabled
                        || state == HyperVMover.VMState.Suspended;
                }

                return false;
            }
        }

        public BindingList<VirtualMachine> Machines { get; private set; }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged = delegate { };

        #endregion

    }
}
